package model

import (
	"fmt"
	"gorm.io/gorm"
	"gowork/weChat/utils"
	"sync"
	"time"
)

type Friends struct {
	Id int64 `gorm:"primaryKey"`
	OwnId int64
	FriendId int64
	Remarks string
	CreatedAt time.Time
	UpdatedAt time.Time
}

func (f *Friends) AsyncOperation( friend *Friends) (map[string] interface{}, error){

	var tx_list []*gorm.DB

	var wg sync.WaitGroup
	wg.Add(3)

	var c bool
	c = false

	for i:=0; i<3; i++ {
		tx := Db.Begin()
		tx_list = append(tx_list, tx)
	}

	go f.AsyncCreate(friend, tx_list[0], &wg, &c)

	go f.AsyncUpdate(tx_list[1], &wg, &c)

	go f.AsyncDelete(tx_list[2], &wg, &c)

	wg.Wait()

	if c == true{
		for _, t := range tx_list {
			t.Rollback()
		}

		return map[string]interface{}{"code":400, "message":"失败", "data":nil}, fmt.Errorf("数据库操作失败！")

	}else {
		for _, t := range tx_list {
			t.Commit()
		}
	}

	return map[string]interface{}{"code":200, "message":"成功", "data":nil}, nil
}

func (f *Friends) AsyncCreate( friend *Friends, tx *gorm.DB, wg *sync.WaitGroup, c *bool) {

	defer func() {
		// 捕获异常 防止waitGroup阻塞
		if err := recover(); err != nil {
			wg.Done()
			*c = true
		}
	}()

	friend.Id = new(utils.Worker).GetId()
	friend.CreatedAt = time.Now()
	friend.UpdatedAt = time.Now()

	tx.Create(friend)

	wg.Done()
}

func (f *Friends) AsyncUpdate( tx *gorm.DB, wg *sync.WaitGroup, c *bool) {

	defer func() {
		// 捕获异常 防止waitGroup阻塞
		if err := recover(); err != nil {
			wg.Done()
			*c = true
		}
	}()

	var uf Friends
	uf.Id = 332265027027337218
	tx.First(&uf)

	uf.OwnId = 5537457745
	uf.FriendId = 63634647457
	uf.Remarks = "异步更新"
	uf.CreatedAt = time.Now()
	uf.UpdatedAt = time.Now()

	tx.Save(&uf)

	wg.Done()
}

func (f *Friends) AsyncDelete( tx *gorm.DB, wg *sync.WaitGroup, c *bool) {

	defer func() {
		// 捕获异常 防止waitGroup阻塞
		if err := recover(); err != nil {
			wg.Done()
			*c = true
		}
	}()

	tx.Delete(&Friends{}, 332265027027337219)

	wg.Done()
}

